package com.bbex.controller;

import com.bbex.config.AliYunAuthenticateSigConfig;
import com.bbex.config.UserConfig;
import com.bbex.config.sercurity.RedisSessionUser;
import com.bbex.constant.Constants;
import com.bbex.constant.SercurityConstant;
import com.bbex.disruptor.DisruptorData;
import com.bbex.disruptor.DisruptorManager;
import com.bbex.entity.PlatUser;
import com.bbex.entity.PlatUserOplog;
import com.bbex.entity.UserTagConfig;
import com.bbex.enums.*;
import com.bbex.exception.PlatException;
import com.bbex.google.GoogleAuthenticator;
import com.bbex.pojo.GlobalMessageResponseVo;
import com.bbex.pojo.ResponsePage;
import com.bbex.query.UserLoginLogQuery;
import com.bbex.reactive.data.mongo.domain.UserLoginLog;
import com.bbex.reactive.data.mongo.enums.SecurityLogEnums;
import com.bbex.service.UserLoginLogService;
import com.bbex.service.MessageSendService;
import com.bbex.service.PlatUserService;
import com.bbex.service.SmsMessageService;
import com.bbex.service.UserTagApplyService;
import com.bbex.util.*;
import com.bbex.valid.ValidateFiled;
import com.bbex.valid.ValidateGroup;
import com.bbex.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

//import reactor.core.scheduler.Schedulers;

@RestController
@RequestMapping("/bbuni")
public class LoginController {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    private static Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Resource(name = "stringRedisTemplate")
    ValueOperations<String, String> valOpsStr;

    @Autowired
    private PlatUserService platUserService;
    @Autowired
    private MessageSendService messageSendService;
    /*@Autowired
    private BaiduApiService baiduApiService;
    @Autowired
    private CardRepository cardRepository;*/
    @Autowired
    private UserLoginLogService userLoginLogService;
    @Autowired
    private SmsMessageService smsMessageService;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Value("${password.resetUrl}")
    private String resetUrl = "https://www.bbex.one/bbex/resetPassword";

    @Value("${register.switch}")
    private String registerSwitch = "1";

    @Autowired
    private UserConfig userConfig;

    @Autowired
    private AliYunAuthenticateSigConfig aliYunAuthenticateSigConfig;

    @Autowired
    private UserTagApplyService userTagApplyService ;
    
    /**
     * 密码前端加密后长度变了，不能使用正则
     *
     * @param platUserVO
     * @return
     */
    @ValidateGroup(fileds = {
            @ValidateFiled(index = 0, filedName = "password", notNull = true, errMsg = "请输入格式正确的密码"),
            @ValidateFiled(index = 0, filedName = "mail", regStr = Constants.EMAIL_PATTERN, notNull = true, when = "{\"filedName\":\"registerType\",\"value\":\"2\"}", errMsg = "请输入正确的邮箱"),
            @ValidateFiled(index = 0, filedName = "mobile", notNull = true, errMsg = "请输入正确的手机号"),
            @ValidateFiled(index = 0, filedName = "code", notNull = false, errMsg = "验证码不正确")
    })
    @PostMapping("/login")
    public Mono<GlobalMessageResponseVo> userlogin(PlatUserVO platUserVO) {

        Integer registerType = platUserVO.getRegisterType();
        String validCode = platUserVO.getCode();
        PlatUser platUser = new PlatUser();
        if (registerType == 1) {
            //手机注册,验证验证码
            platUser.setUsername(platUserVO.getMobile());
            platUser.setMobile(platUserVO.getMobile());
            //验证手机验证码
            smsMessageService.validSmsCode(platUserVO.getMobile(), UserVerifiEnum.USER_REGISTER.getCode(), validCode);
        } else {
            //邮箱注册,验证验证码
            messageSendService.mailValid(UserVerifiEnum.USER_REGISTER.getCode(), VerificationCodeType.REGISTER_CODE, platUserVO.getMail(), validCode);
            platUser.setUsername(platUserVO.getMail());
            platUser.setMail(platUserVO.getMail());
        }
        //解密密码
        String password = RsaUtils.decryptByPrivateKey(platUserVO.getPassword(), RsaUtils.DEFAULT_PRIVATE_KEY);
        platUser.setPassword(password);
        platUser.setInviteCode(platUserVO.getInviteCode());
        platUser.setCountryCode(platUserVO.getCountryCode());
        platUser.setCountryId(platUserVO.getCountryId());
        //platUser.setSource(platUserVO.getSource());
        try {
            platUserService.registerPlatUser(platUser, true);
           // neo4jPlatUserService.save(platUser); // 保存用户节点和关系到NEO4J库
        } catch (PlatException platException) {
            if (platException.getCode() == Constants.INVOTE_CODE_SYNC_ERROR) {
                //邀请码冲突，重试
                platUserService.registerPlatUser(platUser, true);
               // neo4jPlatUserService.save(platUser); // 保存用户节点和关系到NEO4J库
            } else {
                throw platException;
            }
        }
        //清楚验证码
        messageSendService.clearValid(MessageTemplateCode.REGISTER_TEMPLATE.getCode(), VerificationCodeType.REGISTER_CODE.getCode(), platUserVO.getMail());
        return Mono.just(GlobalMessageResponseVo.newSuccessInstance("注册成功"));
    }

}
